<?php

/**
 * -- ManiaLive plugin --
 * @name ManiaRecords for ManiaLive
 * @date 05-10-2011
 * @version v1.1.2
 * @website http://tm.maniarecords.org
 * 
 * Thanks to Xymph & Co for the quick Xaseco2
 * Thanks to McRobert for styling the plugin
 * Thanks to uBm for the port to FoxControl
 * Thanks to undef.de for his Records-Eyepiece Implementation
 * Thanks to TheM for the port to ManiaLive
 * Thanks to forza for the TMX-Implementation
 * 
 * @author Bullracing!vni
 * @ported Max "TheM" Klaversma <maxklaversma@gmail.com>
 * @copyright 2011
 * 
 * DO NOT EDIT THIS FILE ! 
 * IF YOU MAKE CHANGES ON THE CODE, YOUR SERVER MAY
 * BE BANNED PERMANENTLY FROM THE MANIARECORDS DATABASE.
 * -----------------------------------------------------------
 * Changes v1.1.2
 * Added /maniarecords command (does the same as /worldrecords)
 * Namechange (WorldRecords --> ManiaRecords)
 * -----------------------------------------------------------
 * Changes v1.1.1
 * Added /worldrecords command (gives recordwindow)
 * Code cleanup
 * -----------------------------------------------------------
 * Changes v1.1.0
 * Fixed bug which prevented the plugin to submit records.
 * Changed to API v4.0.0
 * -----------------------------------------------------------
 * Changes v1.0.9
 * Fixed bug which prevented the WorldRecords to make any connection with the World Database.
 * Cleanup
 * -----------------------------------------------------------
 * Changes v1.0.8
 * Initial ManiaLive port
 * -----------------------------------------------------------
 */

namespace ManiaLivePlugins\MLEPP\ManiaRecords;

use ManiaLive\Utilities\Console;
use ManiaLib\Utils\TMStrings as String;
use ManiaLive\DedicatedApi\Connection;
use ManiaLive\Data\Storage;
use ManiaLive\Utilities\Time;
use ManiaLivePlugins\MLEPP\ManiaRecords\Config;

use ManiaLivePlugins\MLEPP\ManiaRecords\Gui\Windows\listWindow;
use ManiaLivePlugins\MLEPP\ManiaRecords\Gui\Controls\Header;
use ManiaLivePlugins\MLEPP\ManiaRecords\Gui\Controls\Normal;

// threading
use ManiaLive\Threading\Commands\RunCommand;
use ManiaLive\Threading\ThreadPool;
// structures
use ManiaLivePlugins\MLEPP\ManiaRecords\Structures\Data as ReqData;
use ManiaLivePlugins\MLEPP\ManiaRecords\Structures\WorldRecord;
// custom eventes
use ManiaLive\Event\Dispatcher;
use ManiaLivePlugins\MLEPP\ManiaRecords\Events\onDataSync;

class ManiaRecords extends \ManiaLive\PluginHandler\Plugin {
    public $config;
    
    public $wr;
    public $wrcache;
    public $datacache;
    public $wrlastrec;
    public $wrdbcount;
    
    public $itemholderint;
    public $itemholderint2;
    
    public $serverLogin;
    public $serverName;
    public $gameVersion;
    public $serverHash;
    
    public $version = 1;
    public $version_string = '1.1.2';
    
    public $api_path = '/api_v_4_0_0.php';
    public $api_timeout = 10;
    public $api_version = 1;
    public $api_host = 'api.trackmaniaserver.org';
    
    public $controller = '';
    public $lastaction = '';
    public $detailsopen = true;
    
    function onLoad() {
        $this->wr['controller'] = $this->controller = 'ManiaLive r'.\ManiaLiveApplication\Version;
        $this->config = Config::getInstance();
        
        $this->enableDedicatedEvents();
        $this->enableStorageEvents();
        
        $this->setVersion($this->api_version);
        $this->setPublicMethod('getVersion');
        
        $this->api_host = $this->get_api_host();
        
        $cmd = $this->registerChatCommand('maniarecords', 'maniarecordsChat', 0, true);
        $cmd->help = 'Shows the World Records for this track.';
        
        $cmd = $this->registerChatCommand('worldrecords', 'maniarecordsChat', 0, true);
        $cmd->help = 'Shows the World Records for this track.';
        
        $this->gameVersion = $this->connection->getVersion();
        $this->wr['serverlogin'] = $this->serverLogin = $this->storage->serverLogin;
        $this->wr['servername'] = $this->serverName = String::stripAllTmStyle($this->removespecchars($this->storage->server->name));
        $this->wr['serverhash'] = $this->serverHash = $this->contribute();
        $this->wr['version_string'] = $this->version_string;
        
        $this->wr['playermax'] = $this->connection->getMaxPlayers();
        $this->wr['playermax'] = $this->wr['playermax']['CurrentValue'];
        $this->wr['playercount'] = count($this->storage->players);
        
        if($this->gameVersion->name != 'ManiaPlanet') {
            die('############## ManiaRecords-Plugin is for TM2 only! ###################');
        }
        
        Console::println('#######################################'); 
        Console::println('# ManiaRecords v'.$this->version_string); 
        Console::println('# by Bullracing!vni');
        Console::println('# ManiaLive plugin by TheM (MaxSmurf)'); 
        Console::println('# STR: '.$this->serverHash); 
        Console::println('# API: '.$this->api_host); 
        Console::println('#######################################');
        
        $this->initiateConnection();
    }
    
    function initiateConnection() {
        $this->wr['data'] = array();
        $this->wr['Map']['uid'] = $this->removespecchars($this->storage->currentMap->uId);
        $this->wr['Map']['name'] = $this->removespecchars($this->storage->currentMap->name);
        $this->wr['Map']['aut'] = $this->storage->currentMap->author;
        $this->wr['Map']['gamemode'] = $this->connection->getCurrentGameInfo()->gameMode;
        $this->wr['method'] = 'request';
        
        $response = $this->mm_request($this->wr);
        $this->wrPanel($response['wrs']); 
    }
    
    function maniarecordsChat($login) {
        $answer = array();
        $answer[0] = '';
        $answer[1] = $login;
        $answer[2] = '76426932';
        $this->showDetailedWRs($answer);
    }
    
    function onPlayerConnect($login, $isSpec) {
        $playerObj = $this->storage->getPlayerObject($login);
        if($this->wrcache != '') {
            $this->connection->sendDisplayManialinkPage($playerObj, $this->wrcache, 0, false);
        }
        
        if($this->config->show_welcome === true) {
            $loginObj = $this->storage->getPlayerObject($login);
            $this->connection->chatSendServerMessage('$fff $093This server uses the $l[http://maniarecords.org]$08FManiaRecords$FFF.org$l$093 - Worldrecord Database!', $playerObj);
        }
    }

    function onBeginMap($Map, $warmUp, $matchContinuation) {
        if(!isset($Map) || is_null($Map)) {
            return;
        }
        
        if($Map['UId'] != '' && $Map['Name'] != '') {
            $this->wrPanel_hide();
            if($this->lastaction == 'STARTRACE') {
                return;
            }
            
            $this->lastaction = 'STARTRACE';
            
            $this->wr['data'] = array();
            $this->wr['Map']['uid'] = $this->removespecchars($this->storage->currentMap->uId); 
            $this->wr['Map']['name'] = $this->removespecchars($this->storage->currentMap->name);
            $this->wr['Map']['aut'] = $this->storage->currentMap->author; 
            $this->wr['Map']['gamemode'] = $this->connection->getCurrentGameInfo()->gameMode;
            $this->wr['method'] = 'request';
            
            $this->wr['playermax'] = $this->connection->getMaxPlayers();
            $this->wr['playermax'] = $this->wr['playermax']['CurrentValue'];
            $this->wr['playercount'] = count($this->storage->players);
            
            $response = $this->mm_request($this->wr);
            if(!isset($response['wrs'])) {
                $response['wrs'] = array();
                $wrlastrec = 0; 
                $wrdbcount = 0; 
                if($this->config->show_wr_callout === true) {
                    $this->connection->chatSendServerMessage('$fff $093This track does not have any World Records (yet)!');
                    Console::println('[WR] No WRs on this track!');
                } else {
                    Console::println('[WR] [NoDisplay] No WRs on this track!');
                }
            } else { 
                $wrlastrec = $response['wrs'][count($response['wrs'])-1]['record']; 
                $wrdbcount = count($response['wrs']);
                $span = Time::fromTM($wrlastrec-$response['wrs'][0]['record']); 
                if($this->config->show_wr_callout === true) {
                    $this->connection->chatSendServerMessage('$fff $093The World Record on $fff$l[tm.maniarecords.org/?a=trackinfo&uid='.$Map['UId'].']'.$Map['Name'].'$l$z$s$093 is driven by $fff'.$response['wrs'][0]['nickname'].'$z$s$093 with a time of $fff'.Time::fromTM($response['wrs'][0]['record']).'$093!');
                    Console::println('[WR] First WR: '.Time::fromTM($response['wrs'][0]['record']).' - Last WR: '.Time::fromTM($wrlastrec).' Difference: '.$span.' on '.$Map['Name']);
                } else {
                    Console::println('[WR] [NoDisplay] First WR: '.Time::fromTM($response['wrs'][0]['record']).' - Last WR: '.Time::fromTM($wrlastrec).' Difference: '.$span.' on '.$Map['Name']);
                }
            }
            $this->wrPanel($response['wrs']); 
        }
    }
    
    public function onEndMap($rankings, $map, $wasWarmUp, $matchContinuesOnNextMap, $restartMap){
        $this->wrPanel_hide(); 
        
        if($this->lastaction == 'ENDRACE') {
            return;
        }
        
        $this->lastaction = 'ENDRACE';
        $this->wr['method'] = 'submit';
        $this->wr['Map']['uid'] = $this->removespecchars($this->storage->currentMap->uId); 
        $this->wr['Map']['name'] = $this->removespecchars($this->storage->currentMap->name); 
        $this->wr['Map']['aut'] = $this->storage->currentMap->author;
        $this->wr['Map']['gamemode'] = $this->connection->getCurrentGameInfo()->gameMode;
        $response = $this->mm_request($this->wr);
         
        if(!isset($response['wrs'])) {
            $response['wrs'] = array();
            $wrlastrec = 0; 
            $wrdbcount = 0; 
            if($this->config->show_wr_callout === true) {
                $this->connection->chatSendServerMessage('$fff $093This track does not have any World Records (yet)!');
                Console::println('[WR] No WRs on this track!');
            } else {
                Console::println('[WR] [NoDisplay] No WRs on this track!');
            }
        } else { 
            $wrlastrec = $response['wrs'][count($response['wrs'])-1]['record']; 
            $wrdbcount = count($response['wrs']);
            $span = Time::fromTM($wrlastrec-$response['wrs'][0]['record']); 
            if($this->config->show_wr_callout === true) {
                $this->connection->chatSendServerMessage('$fff $093The World Record on $fff$l[tm.maniarecords.org/?a=trackinfo&uid='.$this->storage->currentMap->uId.']'.$this->storage->currentMap->name.'$l$z$s$093 is driven by $fff'.$response['wrs'][0]['nickname'].'$z$s$093 with a time of $fff'.Time::fromTM($response['wrs'][0]['record']).'$093!');
                Console::println('[WR] First WR: '.Time::fromTM($response['wrs'][0]['record']).' - Last WR: '.Time::fromTM($wrlastrec).' Difference: '.$span.' on '.$map['Name']);
            } else {
                Console::println('[WR] [NoDisplay] First WR: '.Time::fromTM($response['wrs'][0]['record']).' - Last WR: '.Time::fromTM($wrlastrec).' Difference: '.$span.' on '.$map['Name']);
            }
        }
        $this->wrPanel($response['wrs']);
    }
    
    function onPlayerFinish($playerUid, $login, $timeOrScore) {
        $login = $login; 
        $score = $timeOrScore;
        $loginObj = $this->storage->getPlayerObject($login);
        $nickname = $loginObj->nickName;
        
        if(isset($this->wr['cplog'][$login])) {
            $cps = $this->wr['cplog'][$login]; 
        } else {
            $cps = array();
        }
         
        $this->wr['cplog'][$login] = array();
        
        if($score) {
            if(!isset($this->wr['data'][$login]) || (!isset($this->wr['data'][$login]['best'])) || ($this->wr['data'][$login]['best'] > $score)) { 
                $this->wr['data'][$login]['best'] = $score; 
                $this->wr['data'][$login]['nickname'] = $this->removespecchars($nickname); 
                $this->wr['data'][$login]['nicknameclean'] = String::stripAllTmStyle($this->removespecchars($nickname)); 
                $this->wr['data'][$login]['timestamp'] = time(); 
                $this->wr['data'][$login]['cp'] = $cps; 
                
                $addnew = true; 
                $showchat = false; 
                $inranks = false; 
                
                if($this->datacache['wrs']) {
                    $k = 0;
                    foreach($this->datacache['wrs'] as $record ) { 
                        if(($record['login'] == $login) && ($record['record'] > $score)) {
                            unset($this->datacache['wrs'][$k]);
                            $addnew = true;
                            $showchat = true;
                            $inranks = true;
                        }
                        
                        if(($record['login'] == $login) && ($record['record'] <= $score)) {
                            $addnew = false;
                            $showchat = false;
                            $inranks = true; 
                        }
                        $k++;
                    }
                    
                    $this->datacache['wrs'] = array_values($this->datacache['wrs']);
                }
                
                if($addnew == true) {
                    $this->datacache['wrs'][] = array('login' => $login, 'nickname' => $this->removespecchars($nickname), 'record' => $score);
                    $this->wrPanel($this->datacache['wrs']);
                }
                
                if($inranks && $showchat) {
                    $newrecords = $this->array_sort_int($this->datacache['wrs'], 'record', 'timestamp');
                    for($ranking = 0; $ranking < count($newrecords); $ranking++) { 
                        if($newrecords[$ranking]['login'] == $login) {
                            if($ranking+1 <= 30) {
                                if($this->config->show_rank_notifications === true) {
                                    if($ranking+1 <= $this->config->show_public_notification_rank) { 
                                        $this->connection->chatSendServerMessage('$fff $fff'.$nickname.'$z$s $093gained the $fff'.($ranking+1).'.$093 World Record with a time of $FFF'.Time::fromTM($newrecords[$ranking]['record']).'$093!');
                                    } else { 
                                        $this->connection->chatSendServerMessage('$fff $093Congratulations! You claimed the $fff'.($ranking+1).'.$093 World Record with a time of $FFF'.Time::fromTM($newrecords[$ranking]['record']).'$093!', $login);
                                    } 
                                }
                            }
                            break; 
                        }
                    }
                } elseif(!$inranks && !$showchat) {
                    $newrecords = $this->array_sort_int($this->datacache['wrs'], 'record', 'timestamp');
                    for($ranking = 0; $ranking < count($newrecords); $ranking++) { 
                        if($ranking < 30) {
                            if($newrecords[$ranking]['login'] == $login) { 
                                if($ranking+1 <= 30) { 
                                    if($this->config->show_rank_notifications === true) { 
                                        if($ranking+1 <= $this->config->show_public_notification_rank) {
                                            $this->connection->chatSendServerMessage('$fff $fff'.$nickname.'$z$s $093gained the $fff'.($ranking+1).'.$093 World Record with a time of $FFF'.Time::fromTM($newrecords[$ranking]['record']).'$093!'); 
                                        } else {
                                            $this->connection->chatSendServerMessage('$fff $093Congratulations! You claimed the $fff'.($ranking+1).'.$093 World Record with a time of$FFF'.Time::fromTM($newrecords[$ranking]['record']).'$093!', $login); 
                                        }
                                    } 
                                } 
                                break;
                            } 
                        }
                    }
                }
            } 
        }
    }
    
    function onPlayerCheckpoint($playerUid, $playerLogin, $timeScore, $currentLap, $checkpointIndex) {
        $this->wr['cplog'][$playerLogin][] = $timeScore;
    }
    
    function onPlayerManialinkPageAnswer($playerUid, $login, $answer, array $entries) {
        $array = array();
        $array[0] = $playerUid;
        $array[1] = $login;
        $array[2] = $answer;
        $this->showDetailedWRs($array);
    }
    
    function wrPanel_hide() {
        $xml = '<manialink id="90120002" version="0"></manialink>'; 
        $this->connection->sendDisplayManialinkPage(null, $xml, 0, false); 
        $this->detailsopen = false;
    }
    
    function wrPanel($table) { 
        if($this->lastaction == 'STARTRACE') {
            $posx = $this->config->posX_race;
            $posy = $this->config->posY_race;
            $maxwrs = $this->config->maxwrs_race; 
            $stylewr = $this->config->style_Racewr; 
            $substylewr = $this->config->substyle_Racewr; 
            $styleTitlewr = $this->config->style_RaceTitlewr; 
            $substyleTitlewr = $this->config->substyle_RaceTitlewr; 
            $TextColorwr = $this->config->style_Color_TitlewrRace; 
            $styleIconwr = $this->config->style_Icon_Racewr; 
            $substyleIconwr = $this->config->substyle_Icon_Racewr; 
            $TextColorPositionwr = $this->config->style_RacePositionwr; 
            $TextColorTimewr = $this->config->style_RaceTimewr; 
            $backdark = $this->config->style_RaceBackdark; 
        } else {
            $posx = $this->config->posX_scores;
            $posy = $this->config->posY_scores;
            $maxwrs = $this->config->maxwrs_score;
            $stylewr = $this->config->style_Scorewr; 
            $substylewr = $this->config->substyle_Scorewr; 
            $styleTitlewr = $this->config->style_ScoreTitlewr; 
            $substyleTitlewr = $this->config->substyle_ScoreTitlewr; 
            $TextColorwr = $this->config->style_Color_TitlewrScore; 
            $styleIconwr = $this->config->style_Icon_Scorewr; 
            $substyleIconwr = $this->config->substyle_Icon_Scorewr; 
            $TextColorPositionwr = $this->config->style_ScorePositionwr; 
            $TextColorTimewr = $this->config->style_ScoreTimewr;
            $backdark = $this->config->style_ScoreBackdark; 
        } 
        
        $table = $this->array_sort_int($table, 'record', 'timestamp'); 
        $height_head = -3; 
        $height_recs = $maxwrs*($this->config->fontsize+0.5);
        if(count($table) > $maxwrs) {
            $maxwrs -= 1;
        }
         
        if(count($table) > $maxwrs) {
            $reccount = $maxwrs+1.5;
        } else {
            $reccount = count($table)+0.5;
        } 
        
        $xml = '<manialink id="90120001" version="0">
       <frame posn="'.$posx.' '.$posy.' 0">
          <quad posn="0 0 0" sizen="15.5 '.(abs($height_head) + $height_recs + 1).'" style="'.$stylewr.'" substyle="'.$substylewr.'" action="76426932" ></quad>
          <quad posn="0.4 -0.36 3" sizen="14.7 2" style="'.$styleTitlewr.'" substyle="'.$substyleTitlewr.'" ></quad>';
        $xml .= '<quad posn="0.4 -0.36 3.1" sizen="2.6 2.6" style="'.$styleIconwr.'" substyle="'.$substyleIconwr.'"/>';
        $xml .= '<label posn="1 -0.8 3.2" sizen="15.5 '.(abs($height_head)).'" halign="left" valign="top" textsize="1" scale="0.9" textcolor="'.$TextColorwr.'" text="        ManiaRecords v'.$this->version_string.'"></label>';
        
        $y = ($height_head-0.5); 
        
        if($this->config->style_DarkenScores && $backdark && count($table)) {
            $xml .= '<quad posn="0.2 '.$height_head.' -1" sizen="15.1 '.($reccount*($this->config->fontsize+0.5)).'" style="BgRaceScore2" substyle="BgScores" ></quad>';
        }
        
        if(isset($this->wr['Map']['uid'])) { 
            if($table) {
                $count = 0;
                foreach($table as $record) { 
                    if($count++ >= $maxwrs) {
                        break;
                    } 
                    
                    $xml .= '<label posn="0.5 '.$y.' 0" sizen="2 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="'.$TextColorPositionwr.'" text="'.$count.'."></label>'; 
                    $xml .= '<label posn="1.9 '.$y.' 0" sizen="5 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="'.$TextColorTimewr.'" text="'.Time::fromTM($record['record']).'"></label>'; 
                    $xml .= '<label posn="6 '.$y.' 0" sizen="10.4 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="FFFF" text="'.$record['nickname'].'"></label>'; 
                    $y -= ($this->config->fontsize+0.5);
                }
                
                if(count($table) > $maxwrs) { 
                    if(count($table)-1 >= 29) {
                        $lastpos = 29;
                    } else {
                        $lastpos = count($table)-1;
                    }
                     
                    $record = $table[$lastpos]; 
                    $xml .= '<label posn="0.5 '.$y.' 0" sizen="2 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="'.$TextColorPositionwr.'" text="'.($lastpos+1).'."></label>'; 
                    $xml .= '<label posn="1.9 '.$y.' 0" sizen="5 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="'.$TextColorTimewr.'" text="'.Time::fromTM($record['record']).'"></label>'; 
                    $xml .= '<label posn="6 '.$y.' 0" sizen="10.4 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="FFFF" text="'.$record['nickname'].'"></label>'; 
                    $y -= ($this->config->fontsize+0.5);
                } 
            } else { 
                $xml .= '<label posn="0.5 '.$y.' 0" sizen="2 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="'.$TextColorPositionwr.'" text="--."></label>'; 
                $xml .= '<label posn="1.9 '.$y.' 0" sizen="5 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="0F0F" text="-:--.---"></label>'; 
                $xml .= '<label posn="6 '.$y.' 0" sizen="10.4 '.($this->config->fontsize+0.5).'" halign="left" valign="top" scale="0.9" textsize="'.$this->config->fontsize.'" textcolor="FFFF" text="--"></label>'; 
            }
        } else { 
            $xml .= '<label posn="1 '.$y.' 0" sizen="20 '.($this->config->fontsize+0.5).'" halign="left" valign="top" textsize="'.$this->config->fontsize.'" textcolor="FFFF" text="Receiving data"></label>';
        }
        
        $xml .= '
    	</frame>
    	</manialink>'; 
        $this->connection->sendDisplayManialinkPage(null, $xml, 0, false); 
        $this->wrcache = $xml;
    }
    
    function showDetailedWRs($answer) { 
        $table = $this->array_sort_int($this->datacache['wrs'], 'record', 'timestamp');
        $player = $this->storage->getPlayerObject($answer[1]);
        
        if($answer[2] == '76426932') {
            if(!empty($table)) {
                $window = listWindow::Create($answer[1]);
        		$window->setSize(180, 95);
        		$window->clearAll();
        		// prepare cols ...
        		$window->addColumn('Rec', 0.1);
        		$window->addColumn('Time', 0.3);
                $window->addColumn('Nickname', 0.4);
                $window->addColumn('Link', 0.2);
        
        		// refresh records for this window ...
        		$window->clearItems();
        		$id = 1;
        		foreach($table as $record) {
                    if($id < 31) {
            			$entry = array
            			(
            				'Rec' => $id,
            				'Time' => Time::fromTM($record['record']),
                            'Nickname' => $record['nickname'],
                            'Link' => '$l[http://worldranking.trackmaniaserver.org/?a=players&login='.$record['login'].']Click$l'
            			);
            			$id++;
            			$window->addItem($entry);
                    }
        		}
        
        		$window->centerOnScreen();
        		$window->show();
            } else {
                $this->connection->chatSendServerMessage('$fff $093This track does not have any World Records yet!', $answer[1]);
            }
            $this->detailsopen = true;
        }
        
        if($answer[2] == '76426933') {
            $xml = '<manialink id="90120002">
    		</manialink>';
            $this->connection->sendDisplayManialinkPage($player, $xml, 0, false); 
        }
    }
    
    function mm_request($data) {
        $data_to_send = 'data='.$this->build_request($data); 
        $fp = fsockopen($this->api_host, 80, $errno, $errstr, $this->api_timeout); 
        fputs($fp, "POST ".$this->api_path." HTTP/1.1\r\n"); 
        fputs($fp, "Host: ".$this->api_host."\r\n"); 
        fputs($fp, "Referer: ".$this->serverLogin."\r\n"); 
        fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
        fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n"); 
        fputs($fp, "Connection: close\r\n\r\n"); 
        fputs($fp, $data_to_send);
        
        $res = ""; 
        while(!feof($fp)) { 
            $res .= fgets($fp, 1024); 
        } 
        
        $result = explode("\r\n\r\n", $res, 2);
        $header = isset($result[0]) ? $result[0] : '';
        $content = isset($result[1]) ? $result[1] : ''; 
        fclose($fp); 
        $ret = unserialize(($content)); 
        $this->datacache = $ret; 
        if(isset($ret['info'])) {
            $this->connection->chatSendServerMessage('$fff $093'.$ret['info']);
        } 
        return $ret;
    }
    
    function get_api_host() {
        $data_to_send = 'get=apihost'; 
        $fp = fsockopen('api.trackmaniaserver.org', 80, $errno, $errstr, $this->api_timeout); 
        fputs($fp, "POST /redirector.php HTTP/1.1\r\n"); 
        fputs($fp, "Host: api.trackmaniaserver.org\r\n"); 
        fputs($fp, "Referer: ".$this->serverLogin."\r\n"); 
        fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
        fputs($fp, "Content-length: ". strlen($data_to_send) ."\r\n"); 
        fputs($fp, "Connection: close\r\n\r\n"); 
        fputs($fp, $data_to_send); 
        
        $res = ""; 
        while(!feof($fp)) { 
            $res .= fgets($fp, 1024); 
        } 
        fclose($fp);
        $result = explode("\r\n\r\n", $res, 2);
        $header = isset($result[0]) ? $result[0] : '';
        $content = isset($result[1]) ? $result[1] : ''; 
        return $content;
    }
    
    function build_request($data) { 
        $reqdata = array();
        $reqdata['method'] = $data['method'];
        $reqdata['svr']['login']= $data['serverlogin']; 
        $reqdata['svr']['name']= base64_encode($data['servername']); 
        $reqdata['svr']['hash']= $data['serverhash']; 
        $reqdata['svr']['contr'] = $data['controller']; 
        $reqdata['svr']['ver']= $data['version_string'];
        $reqdata['svr']['pmax']= $data['playermax']; 
        $reqdata['svr']['pcur']= $data['playercount'];
        $reqdata['cha']['uid']= $data['Map']['uid']; 
        $reqdata['cha']['name']= base64_encode($data['Map']['name']); 
        $reqdata['cha']['gamemode'] = $data['Map']['gamemode'];
        $reqdata['cha']['aut'] = $data['Map']['aut'];
        $reqdata['pla'] = array(); 
        
        foreach ($data['data'] as $login => $values) {
            $item = array();
            $item['login'] = $login;
            $item['nickname'] = base64_encode($values['nickname']);
            $item['score'] = $values['best'];
            
            if($values['cp']) {
                $item['ctrl'] = $values['cp'][count($values['cp'])-1];
                
                $item['allcps'] = '';
                $cpnum = 0;
                foreach($values['cp'] as $cp) {
                    if($cpnum > 0) {
                        $item['allcps'] .= ',';
                    }
                    $item['allcps'] .= $cp;
                    $cpnum++;
                }
            }
            
            if($this->wrdbcount >= 30) { 
                if($values['best'] <= $wrlastrec) {
                    $reqdata['pla'][] = $item; 
                }
            } else { 
                $reqdata['pla'][] = $item;
            } 
        }
        return urlencode(base64_encode(serialize($reqdata)));
    } 
        
    function removespecchars($text) { 
        $rem = array("'", '\\', '"', "\\", '/', ':', '{', '}');
        return str_replace($rem,'',$text);
    }
    
    function contribute() {
        return md5(filesize(__FILE__));
    }
    
    function array_sort_int($array_unsorted, $item, $item2 = false) { 
        if(!is_array($array_unsorted)) {
            return;
        }
          
        $this->itemholderint = $item;
        $this->itemholderint2 = $item2;
        usort($array_unsorted, array($this, "cmpint")); 
        return $array_unsorted;
    }

    function cmpint($a, $b) { 
        if((int)$a[$this->itemholderint] == (int)$b[$this->itemholderint]) {
            if($this->itemholderint2) {
				return ((int)$a[$this->itemholderint2] < (int)$b[$this->itemholderint2]) ? -1 : 1;
            }
            return 0;
        }
        return ((int)$a[$this->itemholderint] < (int)$b[$this->itemholderint]) ? -1 : 1;
    } 
}
?>